/*
 * PeriodDataGridChart.java
 * Android-Charts
 *
 * Created by limc on 2014.
 *
 * Copyright 2011 limc.cn All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */


package cn.limc.ohoscharts.view;


import cn.limc.ohoscharts.common.ICrossLines;
import cn.limc.ohoscharts.common.IFlexableGrid;
import cn.limc.ohoscharts.entity.IMeasurable;
import ohos.agp.components.AttrSet;
import ohos.agp.components.Component;
import ohos.agp.render.Canvas;
import ohos.agp.utils.Point;
import ohos.app.Context;
import ohos.multimodalinput.event.MmiPoint;
import ohos.multimodalinput.event.TouchEvent;

import java.util.ArrayList;
import java.util.List;

/**
 * <p>en</p>
 * <p>jp</p>
 * <p>cn</p>
 *
 * @author limc
 * @version v1.0 2014/06/19 14:44:11
 */
public abstract class PeriodDataGridChart extends DataGridChart {


  public static final int DEFAULT_ALIGN_TYPE = IFlexableGrid.ALIGN_TYPE_CENTER;


  protected int gridAlignType = DEFAULT_ALIGN_TYPE;


  /**
   * <p>Constructor of PeriodDataGridChart</p>
   * <p>PeriodDataGridChart类对象的构造函数</p>
   * <p>PeriodDataGridChartのコンストラクター</p>
   *
   * @param context
   */
  public PeriodDataGridChart(Context context) {
    super(context);
    // TODO Auto-generated constructor stub
  }

  /**
   * <p>Constructor of PeriodDataGridChart</p>
   * <p>PeriodDataGridChart类对象的构造函数</p>
   * <p>PeriodDataGridChartのコンストラクター</p>
   *
   * @param context
   * @param attrs
   * @param defStyle
   */
  public PeriodDataGridChart(Context context, AttrSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    // TODO Auto-generated constructor stub
  }

  /**
   * <p>Constructor of PeriodDataGridChart</p>
   * <p>PeriodDataGridChart类对象的构造函数</p>
   * <p>PeriodDataGridChartのコンストラクター</p>
   *
   * @param context
   * @param attrs
   */
  public PeriodDataGridChart(Context context, AttrSet attrs) {
    super(context, attrs);
    // TODO Auto-generated constructor stub
  }

  /**
   * <p>
   * initialize degrees on X axis
   * </p>
   * <p>
   * X軸の目盛を初期化
   * </p>
   * <p>
   * 初始化X轴的坐标值
   * </p>
   */
  protected void initAxisX(Canvas canvas) {
    List<String> titleX = new ArrayList<String>();
    if (null != stickData && stickData.size() > 0) {
      float average = getDisplayNumber() / simpleGrid.getLongitudeNum();
      for (int i = 0; i < simpleGrid.getLongitudeNum(); i++) {
        int index = getDisplayFrom() + (int) Math.floor(i * average);
        if (index > getDisplayFrom() + getDisplayNumber() - 1) {
          index = getDisplayFrom() + getDisplayNumber() - 1;
        }
        titleX.add(formatAxisXDegree(stickData.get(index).getDate()));
      }
      titleX.add(formatAxisXDegree(stickData.get(getDisplayFrom() + getDisplayNumber() - 1).getDate()));
    }
    simpleGrid.setLongitudeTitles(titleX, canvas);
  }

  /**
   * <p>
   * initialize degrees on Y axis
   * </p>
   * <p>
   * Y軸の目盛を初期化
   * </p>
   * <p>
   * 初始化Y轴的坐标值
   * </p>
   */
  protected void initAxisY(Canvas canvas) {
    this.calcValueRange();
    List<String> titleY = new ArrayList<String>();
    double average = (maxValue - minValue) / simpleGrid.getLatitudeNum();

    // calculate degrees on Y axis
    for (int i = 0; i < simpleGrid.getLatitudeNum(); i++) {
      String value = formatAxisYDegree(minValue + i * average);
//			if (value.length() < super.getLatitudeMaxTitleLength()) {
//				while (value.length() < super.getLatitudeMaxTitleLength()) {
//					value = " " + value;
//				}
//			}
      titleY.add(value);
    }
    // calculate last degrees by use max value
    String value = formatAxisYDegree(maxValue);
//		if (value.length() < super.getLatitudeMaxTitleLength()) {
//			while (value.length() < super.getLatitudeMaxTitleLength()) {
//				value = " " + value;
//			}
//		}
    titleY.add(value);

    simpleGrid.setLatitudeTitles(titleY, canvas);
  }


  public float longitudePostOffset() {
    if (gridAlignType == IFlexableGrid.ALIGN_TYPE_CENTER) {
      float stickWidth = dataQuadrant.getPaddingWidth() / getDisplayNumber();
      return (this.dataQuadrant.getPaddingWidth() - stickWidth) / (simpleGrid.getLongitudeTitles().size() - 1);
    } else {
      return this.dataQuadrant.getPaddingWidth() / (simpleGrid.getLongitudeTitles().size() - 1);
    }
  }

  public float longitudeOffset() {
    if (gridAlignType == IFlexableGrid.ALIGN_TYPE_CENTER) {
      float stickWidth = dataQuadrant.getPaddingWidth() / getDisplayNumber();
      return dataQuadrant.getPaddingStartX() + stickWidth / 2;
    } else {
      return dataQuadrant.getPaddingStartX();
    }
  }

  @Override
  public void onDraw(Component component, Canvas canvas) {
    super.onDraw(component, canvas);
  }

  protected Point calcTouchedPoint(float x, float y) {
    if (!isValidTouchPoint(x, y)) {
      return new Point(0, 0);
    }
    if (crossLines.getBindCrossLinesToStick() == ICrossLines.BIND_TO_TYPE_NONE) {
      return new Point(x, y);
    } else if (crossLines.getBindCrossLinesToStick() == ICrossLines.BIND_TO_TYPE_BOTH) {
      Point bindPointF = calcBindPoint(x, y);
      return bindPointF;
    } else if (crossLines.getBindCrossLinesToStick() == ICrossLines.BIND_TO_TYPE_HIRIZIONAL) {
      Point bindPointF = calcBindPoint(x, y);
      return new Point(bindPointF.getPointX(), y);
    } else if (crossLines.getBindCrossLinesToStick() == ICrossLines.BIND_TO_TYPE_VERTICAL) {
      Point bindPointF = calcBindPoint(x, y);
      return new Point(x, bindPointF.getPointY());
    } else {
      return new Point(x, y);
    }
  }

  protected Point calcBindPoint(float x, float y) {
    float calcX = 0;
    float calcY = 0;

    int index = calcSelectedIndex(x, y);

    float stickWidth = dataQuadrant.getPaddingWidth() / getDisplayNumber();
    IMeasurable stick = stickData.get(index);
    calcY = (float) ((1f - (stick.getHigh() - minValue)
        / (maxValue - minValue))
        * (dataQuadrant.getPaddingHeight()) + dataQuadrant.getPaddingStartY());
    calcX =
        dataQuadrant.getPaddingStartX() + stickWidth * (index - getDisplayFrom()) + stickWidth / 2;

    return new Point(calcX, calcY);
  }

  /**
   * <p>
   * calculate the distance between two touch points
   * </p>
   * <p>
   * 複数タッチしたポイントの距離
   * </p>
   * <p>
   * 计算两点触控时两点之间的距离
   * </p>
   *
   * @param event
   * @return float
   * <p>
   * distance
   * </p>
   * <p>
   * 距離
   * </p>
   * <p>
   * 距离
   * </p>
   */
  protected float calcDistance(TouchEvent event) {
    MmiPoint point = event.getPointerPosition(event.getIndex());
    if (event.getPointerCount() <= 1) {
      return 0f;
    } else {
      float x = point.getX();
      float y = point.getY();
      return (float) Math.sqrt(x * x + y * y);
    }
  }

  /**
   * @return the gridAlignType
   */
  public int getStickAlignType() {
    return gridAlignType;
  }

  /**
   * @param stickAlignType the gridAlignType to set
   */
  public void setStickAlignType(int stickAlignType) {
    this.gridAlignType = stickAlignType;
  }
}
